package com.ruoyi.zxbh.controller;


import cn.hutool.core.codec.Base64;
import cn.hutool.json.JSONUtil;
import com.arcsoft.face.FaceFeature;
import com.arcsoft.face.FaceSimilar;

import com.ruoyi.zxbh.pojo.FactInfo;
import com.ruoyi.zxbh.pojo.FactInfoLog;
import com.ruoyi.zxbh.service.FactInfoLogService;
import com.ruoyi.zxbh.service.impl.FactInfoServiceImpl;
import com.ruoyi.zxbh.utils.ArcFaceEngineUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author 田国刚
 * @since 2023-04-16
 */
@CrossOrigin(origins = "*")
@RestController
@RequestMapping("/fact-info")
public class FactInfoController {

    @Value("${file.url}")
    public String url;
    @Resource
    FactInfoServiceImpl factInfoService;
    @Resource
    ArcFaceEngineUtil arcFaceEngineUtil;
    @Resource
    FactInfoLogService factInfoLogService;

    @PostMapping("/compareFaceInfo")
    @ResponseBody
    public ResponseEntity<Map<String, Object>> compareFaceInfo(@RequestParam MultipartFile face1, @RequestParam MultipartFile face2) {
        HashMap<String, Object> map = new HashMap<>();
        try {
            // 保存第一个图片
            File tempFile1 = File.createTempFile("face1_", ".jpg");
            try (FileOutputStream fileOutputStream1 = new FileOutputStream(tempFile1)) {
                fileOutputStream1.write(face1.getBytes());
            }

            // 获取第一个人脸特征
            FaceFeature faceFeature1 = arcFaceEngineUtil.getFaceFeature(tempFile1);
            String jsonStr1 = JSONUtil.toJsonStr(faceFeature1);

            // 删除临时文件
            tempFile1.deleteOnExit();

            // 保存第二个图片
            File tempFile2 = File.createTempFile("face2_", ".jpg");
            try (FileOutputStream fileOutputStream2 = new FileOutputStream(tempFile2)) {
                fileOutputStream2.write(face2.getBytes());
            }

            // 获取第二个人脸特征
            FaceFeature faceFeature2 = arcFaceEngineUtil.getFaceFeature(tempFile2);
            String jsonStr2 = JSONUtil.toJsonStr(faceFeature2);

            // 删除临时文件
            tempFile2.deleteOnExit();

            // 将结果放入Map
            map.put("faceInfo1", jsonStr1);
            map.put("faceInfo2", jsonStr2);
            // 比较人脸信息结果
            FaceSimilar faceSimilar = arcFaceEngineUtil.compareFaceFeature(faceFeature1, faceFeature2);
            map.put("faceSimilar", faceSimilar);

            return new ResponseEntity<>(map, HttpStatus.OK);
        } catch (IOException e) {
            // 错误处理
            map.put("error", "文件处理失败：" + e.getMessage());
            return new ResponseEntity<>(map, HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }


    @PostMapping("/save")
    @ResponseBody
    public ResponseEntity<Map<String, Object>> saveFaceInfo(@RequestParam MultipartFile[] files, String name, String remark) throws IOException {

        for (MultipartFile e : files) {
            FileOutputStream fileOutputStream = new FileOutputStream("./1.jpg");
            fileOutputStream.write(e.getBytes());


        }

        FactInfo factInfo = new FactInfo();
        factInfo.setName(name);
        factInfo.setRemark(remark);
        File faceImg = new File("./1.jpg");
        FaceFeature faceFeature = arcFaceEngineUtil.getFaceFeature(faceImg);
        if (faceImg.exists()) {
            faceImg.deleteOnExit();
        }
        String jsonStr = JSONUtil.toJsonStr(faceFeature);
        factInfo.setFaceData(jsonStr);
        HashMap<String, Object> map1 = factInfoService.saveFaceInfo(factInfo);
        map1.put("data", factInfo);
        return new ResponseEntity<>(map1, HttpStatus.OK);

    }

    @PostMapping("/get")
    @ResponseBody
    public ResponseEntity<Map<String, Object>> getAllFaceInfo() {
        HashMap<String, Object> allFaceInfo = factInfoService.getAllFaceInfo();

        return new ResponseEntity<>(allFaceInfo, HttpStatus.OK);

    }

    @PostMapping("/delete")
    @ResponseBody
    public ResponseEntity<Map<String, Object>> deleteFaceInfo(@RequestBody Map<String, Object> resout) {


        Map<String, Object> stringObjectMap = factInfoService.deleteFaceInfo(resout.get("id").toString());

        return new ResponseEntity<>(stringObjectMap, HttpStatus.OK);
    }


    @PostMapping("/check")
    @ResponseBody
    public ResponseEntity<Map<String, Object>> checkFaceInfo(@RequestBody Map<String, Object> resout) throws IOException {
        HashMap<String, Object> map = new HashMap<>();
        String[] imageData = resout.get("imageData").toString().split(",");
        byte[] result = Base64.decode(imageData[1]);
        for (int i = 0; i < result.length; ++i) {
            if (result[i] < 0) {// 调整异常数据
                result[i] += 256;
            }
        }
        String imageId = UUID.randomUUID().toString();
        String imageUrl = "." + File.separator + "image" + File.separator + imageId + ".jpg";
        FileOutputStream fileOutputStream = new FileOutputStream(imageUrl);
        fileOutputStream.write(result);
        fileOutputStream.flush();
        fileOutputStream.close();
        File faceImg = new File(imageUrl);
        FaceFeature faceFeature = null;

        faceFeature = arcFaceEngineUtil.getFaceFeature(faceImg);

        FactInfoLog factInfoLog = new FactInfoLog();
        factInfoLog.setImageUrl(url + imageId);
        factInfoLog.setCreateTime(LocalDateTime.now());

        if (faceFeature == null) {
            map.put("code", 501);
            map.put("message", "无人脸信息！");
            map.put("data", faceFeature);
            return new ResponseEntity<>(map, HttpStatus.OK);
        }
        HashMap<String, Object> userInfo = arcFaceEngineUtil.getUserInfo(faceImg);
        factInfoLog.setFace3D(userInfo.get("3DAngle").toString());
        factInfoLog.setAge(userInfo.get("age").toString());
        factInfoLog.setSex("0".equals(userInfo.get("gender").toString()) ? "男" : "女");
        factInfoLog.setLivingBody("1".equals(userInfo.get("liveness").toString()) ? "正常" : "图片打卡嫌疑");


        List<FactInfo> list = factInfoService.list();
        for (FactInfo e : list) {
            FaceFeature bean = JSONUtil.toBean(e.getFaceData(), FaceFeature.class);

            FaceSimilar faceSimilar = arcFaceEngineUtil.compareFaceFeature(faceFeature, bean);
            if (faceSimilar.getScore() > 0.78) {

                map.put("code", 200);
                map.put("data", userInfo);
                map.put("message", "恭喜" + e.getName() + "登录成功！");
                map.put("userInfo", e);


                factInfoLog.setName(e.getName());
                factInfoLog.setUserId(e.getId());

                factInfoLogService.save(factInfoLog);
                return new ResponseEntity<>(map, HttpStatus.OK);
            }
        }
        map.put("code", 500);
        map.put("message", "非法用户！");
        map.put("data", arcFaceEngineUtil.getUserInfo(faceImg));
        factInfoLogService.save(factInfoLog);
        return new ResponseEntity<>(map, HttpStatus.OK);
    }
}
